package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import io.swagger.models.RefPath;
import io.swagger.models.auth.In;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkspaceService workspaceService;

    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        //设置时间
        List<LocalDate> list = dateList(begin, end);
        List<Integer> sumList  = new ArrayList<>(list.size());
        //设置完成订单数量
        Map map = new HashMap();
        list.forEach(i->{

            LocalDateTime min = LocalDateTime.of(i, LocalTime.MIN);
            LocalDateTime max = LocalDateTime.of(i, LocalTime.MAX);
            map.put("begin",min);
            map.put("end",max);
            map.put("status", Orders.COMPLETED);
            Integer sum = reportMapper.turnoverStatistics(map);
            sum = sum == null?0:sum;
            sumList.add(sum);
        });
        //构造对象
        return TurnoverReportVO.builder()
                .turnoverList(StringUtils.join(sumList,","))
                .dateList(StringUtils.join(list,","))
                .build();
    }

    /**
     * 用户数量统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userReportVO(LocalDate begin, LocalDate end) {
        List<LocalDate> list = dateList(begin, end);

        List<Integer> newUser = new ArrayList<>(list.size());
        List<Integer> allUser = new ArrayList<>(list.size());
        Map map = new HashMap();
        list.forEach(i->{

            LocalDateTime min = LocalDateTime.of(i, LocalTime.MIN);
            LocalDateTime max = LocalDateTime.of(i, LocalTime.MAX);
            map.put("begin",min);
            map.put("end",max);

            Integer nuser = reportMapper.newUser(map);
            Integer auser = reportMapper.allUser(map);
            newUser.add(nuser);
            allUser.add(auser);

        });


        return UserReportVO.builder()
                .newUserList(StringUtils.join(newUser,","))
                .totalUserList(StringUtils.join(allUser,","))
                .dateList(StringUtils.join(list,","))
                .build();

    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> list = dateList(begin, end);
//        private String dateList;
//
//        //每日订单数，以逗号分隔，例如：260,210,215
//        private String orderCountList;
//
//        //每日有效订单数，以逗号分隔，例如：20,21,10
//        private String validOrderCountList;
//
//        //订单总数
//        private Integer totalOrderCount;
//
//        //有效订单数
//        private Integer validOrderCount;
//
//        //订单完成率
//        private Double orderCompletionRate;
        List<Integer> orderCountList = new ArrayList<>(list.size());
        List<Integer> validOrderCountList = new ArrayList<>(list.size());
        Map map = new HashMap();
        list.forEach(i->{
            LocalDateTime min = LocalDateTime.of(i, LocalTime.MIN);
            LocalDateTime max = LocalDateTime.of(i, LocalTime.MAX);
            map.put("begin",min);
            map.put("end",max);
            map.put("status",Orders.COMPLETED);
            //查询每日订单数
            Integer orderCount = reportMapper.orderCountList(map);
            orderCountList.add(orderCount);
            //查询每日有效订单数
            Integer validOrderCount = reportMapper.validOrderCountList(map);
            validOrderCountList.add(validOrderCount);
        });
        //获取订单总数
        Integer integer = orderCountList.stream().reduce(Integer::sum).get();
        //获取有效订单总数
        Integer integer1 = validOrderCountList.stream().reduce(Integer::sum).get();
        //订单完成率
        Double d = (integer1 + 0.0)/ integer;
        return OrderReportVO.builder()
                .totalOrderCount(integer)
                .validOrderCount(integer1)
                .dateList(StringUtils.join(list,","))
                .orderCompletionRate(d)
                .validOrderCountList(StringUtils.join(validOrderCountList,","))
                .orderCountList(StringUtils.join(orderCountList,","))
                .build();
    }

    /**
     * 查询销量排名
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO goodsSales(LocalDate begin, LocalDate end) {
        Map map = new HashMap();

        LocalDateTime min = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime max = LocalDateTime.of(end, LocalTime.MAX);
        map.put("begin",min);
        map.put("end",max);

        List<GoodsSalesDTO> list = reportMapper.top10(map);


        return SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(list.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()), ","))
                .numberList(StringUtils.join(list.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()), ","))
                .build();

    }

    /**
     * 导出Excel报表接口
     * @param res
     */
    @Override
    public void export(HttpServletResponse res)  {
        //打开工作表
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("运营数据报表模板.xlsx");
        try {
            assert resourceAsStream != null;
            XSSFWorkbook x = new XSSFWorkbook(resourceAsStream);
            XSSFSheet sheet = x.getSheet("Sheet1");
            XSSFRow row = sheet.getRow(1);
            row.getCell(1).setCellValue(LocalDate.now().minusDays(30) + "至" + LocalDate.now().minusDays(1));
            row = sheet.getRow(3);
            LocalDateTime min = LocalDateTime.of(LocalDate.now().minusDays(30), LocalTime.MIN);
            LocalDateTime max = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MAX);
            BusinessDataVO businessDataVO = workspaceService.businessData(min, max);
//        private Double turnover;//营业额
//        private Integer validOrderCount;//有效订单数
//        private Double orderCompletionRate;//订单完成率
//        private Double unitPrice;//平均客单价
//        private Integer newUsers;//新增用户数
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());
            LocalDate localDate = LocalDate.now().minusDays(30);
            for (int i = 0; i < 30; i++) {
                min = LocalDateTime.of(localDate.plusDays(i), LocalTime.MIN);
                max = LocalDateTime.of(localDate.plusDays(i), LocalTime.MAX);
                businessDataVO = workspaceService.businessData(min,max);
                row = sheet.getRow(i + 7);
                //"	营业额"	"	有效订单"	订单完成率	平均客单价	新增用户数
                row.getCell(1).setCellValue( localDate.plusDays(i).toString() );
                row.getCell(2).setCellValue(businessDataVO.getTurnover());
                row.getCell(3).setCellValue(businessDataVO.getValidOrderCount());
                row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessDataVO.getUnitPrice());
                row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            }
            ServletOutputStream outputStream = res.getOutputStream();
            x.write(outputStream);


            outputStream.close();
            x.close();


        }catch (Exception e){
            System.err.println(e.getMessage() + "我出现了 ===== ");
        }

    }


    public List<LocalDate> dateList(LocalDate begin, LocalDate end){
        List<LocalDate> list = new ArrayList<>();
        LocalDate begin1 = begin;
        while (!begin1.isAfter(end)){
            list.add(begin1);
            begin1 = begin1.plusDays(1);
        }
        return list;
    }
}
